home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Text⁄Files / Writeswell Jr. 1.0.2 Master / Writeswell Jr. Source / MyFiles.c < prev    next >
Text File  |  1992-10-28  |  9KB  |  421 lines

  1. /* MyFiles.c
  2.  * Handle file calls in IAC speller testbed app
  3.  * ©1992 Working Software, Inc.
  4.  * This source code is copyrighted.  Permission is granted to use the Word Services
  5.  * portion of the Writeswell Jr. source code in your own programs, but you 
  6.  * may not distribute the Writeswell Jr. word-processor code as a 
  7.  * commercial product.  If you modify the code, please do not call it 
  8.  * Writeswell Jr. (or Writeswell.)  This will ensure that people understand the 
  9.  * program and don’t have to deal with a number of different versions with 
  10.  * who-knows-what going on in the code.
  11.  * 
  12.  * Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
  13.  * 6 Sep 91 Mike Crawford
  14.  */
  15.  
  16. #include <Files.h>
  17. #include "MyFiles.h"
  18. #include "AppleEvents.h"
  19. #include "TBConstants.h"
  20. #include "TBGlobals.h"
  21. #include "TestBed.h"
  22. #include "Scroll.h"
  23. #include "Gripe.h"
  24.  
  25. #define kZoomIconAllowance    68        /* Width of desktop to show when window zoomed */
  26.  
  27. OSErr SaveStyleResource( void );
  28.  
  29. void DoOpenDialog( void )
  30. {
  31.     SFTypeList    typeList;
  32.     SFReply        reply;
  33.     Point        where;
  34.     OSErr        err;
  35.     
  36.     typeList[ 0 ] = 'TEXT';
  37.  
  38.     /* STUB Center the dialog */
  39.     
  40.     where.h = 50;
  41.     where.v = 50;
  42.  
  43.     SFGetFile( where,
  44.                     "\p",
  45.                     (FileFilterProcPtr)NULL,
  46.                     1,
  47.                     typeList,
  48.                     (DlgHookProcPtr)NULL,
  49.                     &reply );
  50.     
  51.     if ( !reply.good )
  52.         return;
  53.     
  54.     MyOpenSfFile( &reply );
  55.  
  56.     return;
  57. }
  58.  
  59. void DoSave( void )
  60. {
  61.     if ( gDocExists )
  62.         SaveFile();
  63.     else
  64.         DoSaveDialog();
  65.     return;
  66. }
  67.  
  68. void DoSaveDialog( void )
  69. {
  70.     SFReply        reply;
  71.     OSErr        err;
  72.     Point        where;
  73.     
  74.     /* STUB Center the dialog on the screen */
  75.     
  76.     where.h = 100;
  77.     where.v = 50;
  78.  
  79.     /* STUB use the window name as the default name */
  80.     
  81.     SFPutFile( where,
  82.                 "\pSave document as:",
  83.                 "\pUntitled",
  84.                 (ProcPtr)NULL,
  85.                 &reply );
  86.     
  87.     if ( !reply.good )
  88.         return;
  89.     
  90.     /* Try deleting the old file.  It may not exist.
  91.      * STUB Do a GetFileInfo to see if the file already exists
  92.      */
  93.     
  94.     err = FSDelete( reply.fName, reply.vRefNum );
  95.     if ( err && err != fnfErr ){
  96.         Gripe( "\pCould not delete existing file" );
  97.         return;
  98.     }
  99.     
  100.     err = Create( reply.fName,
  101.                     reply.vRefNum,
  102.                     'MiKe',
  103.                     'TEXT' );
  104.     if ( err ){
  105.         Gripe( "\pCould not create new file" );
  106.         return;
  107.     }
  108.     
  109.     if ( err = FSOpen( reply.fName, reply.vRefNum, &gRefNum ) ){
  110.         Gripe( "\pFSOpen failed" );
  111.         return;
  112.     }
  113.     
  114.     err = SetVol( (StringPtr)NULL, reply.vRefNum );
  115.     if ( err ){
  116.         Gripe( "\pCould not set volume" );
  117.         return;
  118.     }
  119.  
  120.     CreateResFile( reply.fName );
  121.     if ( err = ResError() ){
  122.         Gripe( "\pCould not create resource fork of document" );
  123.         return;
  124.     }
  125.  
  126.     gResRefNum = OpenResFile( reply.fName );
  127.     if ( gResRefNum == -1 ){
  128.         err = ResError();
  129.         Gripe( "\pOpenResFile failed" );
  130.         return;
  131.     }
  132.  
  133.     gDocExists = true;
  134.     
  135.     err = SaveFile();
  136.  
  137.     if ( !err ){
  138.         SetWTitle( gDocWindow, reply.fName );
  139.     }
  140.  
  141.     return;
  142. }
  143.  
  144. OSErr SaveFile( void )
  145. {
  146.     OSErr        err;
  147.     TEHandle    textH;
  148.     CharsHandle    textBufHdl;
  149.     long        numChars;
  150.  
  151.     /* STUB should do a "safe save" here.  This is not a safe save - if there is 
  152.      * a failure in here, the file is hosed.
  153.      */
  154.  
  155.     err = SetFPos( gRefNum, fsFromStart, 0L );
  156.     if ( err ){
  157.         Gripe( "\pCould not set file position" );
  158.         return err;
  159.     }
  160.  
  161.     err = SetEOF( gRefNum, 0L );
  162.     if ( err ){
  163.         Gripe( "\pCould not set end of file" );
  164.         return err;
  165.     }
  166.  
  167.     textH = (TEHandle)GetWRefCon( gDocWindow );
  168.     
  169.     textBufHdl = TEGetText( textH );
  170.     
  171.     numChars = GetHandleSize( textBufHdl );
  172.     
  173.     HLock( textBufHdl );
  174.     err = FSWrite( gRefNum, &numChars, *textBufHdl );
  175.     HUnlock( textBufHdl );
  176.     
  177.     if ( err ){
  178.         Gripe( "\pFSWrite failed" );
  179.         return err;
  180.     }
  181.     
  182.     err = SaveStyleResource();
  183.     
  184.     if ( !err )
  185.         gDocDirty = false;
  186.  
  187.     return err;
  188. }
  189.  
  190. OSErr SaveStyleResource( void )
  191. {
  192.     short            curFile;
  193.     StScrpHandle    styleHdl;
  194.     TEHandle        textH;
  195.     Handle            oldStyle;
  196.     short            oldStart;
  197.     short            oldEnd;
  198.     
  199.     curFile = CurResFile();
  200.     
  201.     UseResFile( gResRefNum );
  202.     
  203.     textH = (TEHandle)GetWRefCon( gDocWindow );
  204.     
  205.     oldStart = (*textH)->selStart;
  206.     oldEnd = (*textH)->selEnd;
  207.  
  208.     (*textH)->selStart = 0;
  209.     (*textH)->selEnd = 32767;
  210.  
  211.     styleHdl = GetStylScrap( textH );
  212.     
  213.     (*textH)->selStart = oldStart;
  214.     (*textH)->selEnd = oldEnd;
  215.  
  216.     if ( !styleHdl ){
  217.         UseResFile( curFile );
  218.         return memFullErr;
  219.     }
  220.     
  221.     oldStyle = Get1Resource( 'styl', rStyleID );
  222.     
  223.     if ( oldStyle ){
  224.         RmveResource( oldStyle );    
  225.     }
  226.  
  227.     AddResource( styleHdl, 'styl', rStyleID, "\pText Styles" );
  228.     ChangedResource( styleHdl );
  229.     WriteResource( styleHdl );
  230.  
  231.     UpdateResFile( gResRefNum );
  232.  
  233.     UseResFile( curFile );
  234.  
  235.     return noErr;
  236. }
  237.  
  238. OSErr MyOpenSfFile( SFReply *replyPtr )
  239. {
  240.     OSErr            err;
  241.     Rect            txRect;
  242.     char            *textBuf;
  243.     long            bytesRead;
  244.     TEHandle        textH;
  245.     StScrpHandle    styleHdl;
  246.     ParamBlockRec    fPB;
  247.     long            fileSize;
  248.     
  249.     if ( err = FSOpen( replyPtr->fName, replyPtr->vRefNum, &gRefNum ) ){
  250.         Gripe( "\pFSOpen failed" );
  251.         return err;
  252.     }
  253.     
  254.     fPB.fileParam.ioCompletion = (ProcPtr)NULL;
  255.     fPB.fileParam.ioNamePtr = (StringPtr)NULL;
  256.     fPB.fileParam.ioVRefNum = replyPtr->vRefNum;
  257.     
  258.     err = PBSetVol( &fPB, false );
  259.     if ( err ){
  260.         Gripe( "\pPBSetVol failed in MyOpenSpecFile" );
  261.         return err;
  262.     }
  263.  
  264.     gResRefNum = OpenResFile( replyPtr->fName );
  265.     
  266.     /* The existing file may have had no resource fork.  It's not clear to me
  267.      * what the right thing to do is.  I am inclined to not create one - if the
  268.      * user wants to save styles, she could do a "Save As" to create a new file
  269.      * with the style resource.
  270.      */
  271.  
  272.     styleHdl = (StScrpHandle)NULL;            /* In case there's no resource fork */
  273.  
  274.     if ( gResRefNum != -1 ){
  275.  
  276.         /* Load the style resource */
  277.         
  278.         styleHdl = (StScrpHandle)Get1Resource( 'styl', rStyleID );
  279.         
  280.         /* styleHdl might be nil - we check for this later */
  281.     }
  282.     
  283.     if ( MakeNewWindow() ){
  284.         Gripe( "\pMakeNewWindow failed" );
  285.         return err;
  286.     }
  287.     
  288.     gDocExists = true;
  289.  
  290.     SetWTitle( gDocWindow, replyPtr->fName );
  291.  
  292.     textH = (TEHandle)GetWRefCon( gDocWindow );
  293.  
  294.     /* Styled TextEdit requires that we insert the text and the style at the same time.
  295.      * I originally had a loop that did a read with a small buffer, but in order to
  296.      * set both the text and the style, I need to read all of the text in a single
  297.      * chunk, and set it in a single chunk.
  298.      */
  299.     
  300.     err = GetEOF( gRefNum, &fileSize );
  301.     if ( err ){
  302.         Gripe( "\pCould not get file size" );
  303.         return err;
  304.     }
  305.  
  306.     textBuf = NewPtr( fileSize );
  307.     if ( !textBuf ){
  308.         Gripe( "\pOut of memory" );
  309.         return memFullErr;
  310.     }
  311.  
  312.     bytesRead = fileSize;
  313.  
  314.     err = FSRead( gRefNum, &bytesRead, textBuf );
  315.     
  316.     if ( err ){
  317.         Gripe( "\pCould not read the file" );
  318.         DisposPtr( textBuf );
  319.         return err;
  320.     }
  321.     
  322.     /* styleHdl might be nil.  This is OK */
  323.     TEStylInsert( textBuf, bytesRead, styleHdl, textH );
  324.     
  325.     if ( styleHdl != (StScrpHandle)NULL );
  326.         ReleaseResource( styleHdl );
  327.  
  328.     TESetSelect( 0L, 0L, textH );
  329.  
  330.     SetVertScroll( gDocWindow, gVertScroll );
  331.  
  332.     return noErr;
  333. }
  334.  
  335. OSErr MyOpenSpecFile( FSSpec *specPtr )
  336. {
  337.     WDPBRec            wPB;
  338.     SFReply            reply;
  339.     OSErr            err;
  340.     
  341.     wPB.ioCompletion = (ProcPtr)NULL;
  342.     wPB.ioVRefNum = specPtr->vRefNum;
  343.     wPB.ioWDDirID = specPtr->parID;
  344.     wPB.ioWDProcID = 'ERIK';            /* This is traditional; no real point to it */
  345.     wPB.ioNamePtr = (StringPtr)NULL;
  346.  
  347.     err = PBOpenWD( &wPB, false );
  348.     if ( err ){
  349.         Gripe( "\pPBOpenWD failed in MyOpenSpecFile" );
  350.         return err;
  351.     }
  352.     
  353.     BlockMove( specPtr->name, reply.fName, (specPtr->name)[0] + 1 );
  354.     
  355.     reply.vRefNum = wPB.ioVRefNum;
  356.     
  357.     reply.good = true;
  358.     
  359.     reply.copy = false;
  360.     
  361.     reply.fType = 'TEXT';            /* STUB Do a GetFileInfo to find the type */
  362.     
  363.     reply.version = 0;
  364.     
  365.     err = MyOpenSfFile( &reply );
  366.     
  367.     return err;
  368. }
  369.  
  370. OSErr MakeNewWindow( void )
  371. {
  372.     OSErr        err;
  373.     Rect        txRect;
  374.     TEHandle    textH;
  375.     Rect        *zoomArray;
  376.  
  377.     gDocWindow = GetNewWindow( kDocWindowID, (Ptr)NULL, (WindowPtr) -1 );
  378.     if ( !gDocWindow ){
  379.         Gripe( "\pGetNewWindow failed" );
  380.         return err;
  381.     }
  382.     
  383.     SetPort( gDocWindow );
  384.     
  385.     gDocDirty = false;
  386.     gDocExists = false;
  387.     
  388.     GetTERect( &( thePort->portRect ), &txRect );
  389.     
  390.     textH = TEStylNew( &txRect, &txRect );
  391.     
  392.     if ( !textH ){
  393.         Gripe( "\pTENew failed" );
  394.         return memFullErr;
  395.     }
  396.     
  397.     SetWRefCon( gDocWindow, (long)textH );
  398.     
  399.     gVertScroll = GetNewControl( kVertScrollBarID, gDocWindow );
  400.     if ( !gVertScroll )
  401.         return memFullErr;
  402.  
  403.     ( *textH )->clikLoop = (ProcPtr)TrackContentClick;
  404.  
  405.     SizeVertScroll();
  406.  
  407.     SetVertScroll( gDocWindow, gVertScroll );
  408.     
  409.     if ( ((WindowPeek)gDocWindow)->dataHandle != (Handle)NULL ){
  410.         /* Set the zoom state to reveal the disk & trash icons.
  411.          * STUB Make this some kind of preference - inappropriate for Unifinder
  412.          */
  413.     
  414.         zoomArray = (Rect*)*((WindowPeek)gDocWindow)->dataHandle;        /* Warning: Deref handle */
  415.         
  416.         zoomArray[ 1 ].right -= kZoomIconAllowance;
  417.     }
  418.  
  419.     return noErr;
  420.     
  421. }